\chapter{Ядро}
\pagenumbering{arabic}

% % Лицензия на материалы этого текст
% 
% Материалы сайта "Записки дебианщика" написаны virens и доступны на условиях лицензии Creative Commons Attribution-Non-Commercial-Share Alike 3.0 Unported License. Вы можете копировать, распространять, показывать эту работу, и создавать производные работы в некоммерческих целях на условиях:
% 
% 1) обязательной ссылки на автора (virens, http://mydebianblog.blogspot.com/) и
% 
% 2) распространении любых производных работ на условиях этой же лицензии (ссылка на эту лицензию 
% обязательна!).
% 
% Пожалуйста соблюдайте условия лицензии.
% 
% This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. 
\section{Управление ядром Linux реального времени}
Для управления приоритетами ядра есть утилиты из пакета schedutils.


\subsection{Привязка задачи к процессору}
Если у вас многоядерная или многопроцессорная машина, есть смысл некоторые задачи раскидать по процессорам принудительно. Для этих целей есть программа taskset.
\begin{lstlisting}
# taskset -p 1 5907
\end{lstlisting}
Получаем в ответ:
\begin{lstlisting}
pid 5907's current affinity mask: 1
pid 5907's new affinity mask: 2
\end{lstlisting}
Задача, таким образом, перекинута на второй процессор.


\subsection{Изменение приоритета процессов}
Чтобы задача получила приоритет реального времени, следует выполнить команду:
\begin{lstlisting}
# chrt -p 6091
\end{lstlisting}

В ответ должны получить:

\begin{lstlisting}
pid 6091's current scheduling policy: SCHED_OTHER
pid 6091's current scheduling priority: 0
\end{lstlisting}

Это значит, что задача теперь будет выполняться неотложно, с минимально возможными задержками.


\subsection{Изменение приоритета ввода-вывода}
Много задач требуют не только точного интервала исполнения, но и чтобы данные перекачивались как можно быстрее. Для этого можно отдать приоритет ввода-вывода наиболее критичной задаче.  Возможно выставить следующие типы приоритетов: Бездействие (Idle), Наилучшая работа (Best effort) и Реальное время (Real time).


\subsection{Приоритет Idle}
Программа с приоритетом idle получит диступ к диску только тогда, когда никакие другие программы к диску не обращаются в течение определённого времени.

\subsubsection{Приоритет Best effort}
Этот приоритет выбирается по умолчанию для любого процесса, который не требует иного приоритета ввода-вывода. Программы наследуют установки процессорного приоритета для приоритета ввода-вывода, можно так же передавать аргумент от 0 (высокий приоритет) до 7 (низкий приоритет). Ресурсы между приложения с одинаковым приортетом best effort распределяются по принципу "каждой сестре по серьге".

\subsection{Приоритет Real time}
Задачам с приоритетом реального времени выделяется доступ к диску в первую очередь и вне зависимости от происходящего в системе. Поэтому приоритет реального времени следуется использовать осторожно, чтобы не перекрыть кислород другим процессам. Как и в случае приоритета best effort, предусмотрено 8 уровней приоритета, от 0 (высокий приоритет) до 7 (низкий приоритет).

Для выбора приоритета следует указывать параметр -с и значения:

\begin{lstlisting}
-c1 %--- реальное вемя (real time)%
-c2 %--- наилучшая работа (best effort)%
-c3 %--- бездействие (idle)%
\end{lstlisting}

Для указания параметра приоритета используется ключ -nM, где M - число от 0 (высокий приоритет) до 7 (низкий приоритет).

Например, чтобы задать приоритет реального времени с высшим приоритетом для ввода-вывода приложения с идентификатором

\begin{lstlisting}
# ionice -c2 -n0 -p5812
\end{lstlisting}

После этого приложению уже никто не помешает монопольно использовать ввод-вывод.


\section{Как собрать ядро в Линукс}
Если вы столкнулись с необходимостью собрать ядро Linux, наложить патч для ядра Линукс или просто вы уже забыли, как это делается - здесь приводятся рекомендации и ссылки для "быстрого старта".

\subsection{Как собрать или пересобрать ядро Линукс?}
Прежде всего, заполучите статью "Ставим ядро 2.6, или Ядерная физика для домохозяйки" (тут - новая версия этой статьи). Не надо оскорбляться таким названием - это исчерпывающая статья по сборке ядра, её автор, Михаил Зарипов, перевёл на русский почти все опции ядра!

\subsection{Какие могут быть проблемы при сборке ядра?}
Проблем при сборке обычно не бывает, только если вы не намудрили с компилятором или недоустановили его. В процессе сборки проблем не так много, они обычно возникают после сборки ядра по следующим причинам:

\begin{enumerate}
 \item вы не включили в ядро то, что очень нужно, и теперь система не загружается или пропала возможность работы с некоторым оборудованием;
\item вы включили в ядро то, что не надо (особенно с надписью EXPERIMENTAL) и теперь система работает нестабильно или очень медленно или  ядро вываливается в kernel panic;
\item вы взяли нестабильное ядро и/или компилятор в бета-версии/выставили дикие флаги оптимизации - вас предупреждали
\end{enumerate}

\subsection{С чего начать?}
С того, что к сборке ядра нужно подготовиться: это займёт много времени, особенно если вы это делаете в первый раз. У меня пересборка первого ядра заняла 4 часа - вдумчивое чтение статьи, поиск параметра, включение или выключение и так далее. У вас это может занять времени меньше - затем я это и пишу.
Хорошо бы взять конфиг из вашего дистрибутива - дистростроители в сборке ядер понимают, как правило, больше вас, так что не стесняйтесь. Копируем в каталог с ядром и пишем

\begin{lstlisting}
# make oldconfig
\end{lstlisting}

Флажки параметров ядра должны расставиться соответствующем конфигу образом, если только в вашем дистрибутиве не принято накладывать на ядро 33 заплатки. Конфиг так же можно попросить у ближайшего линуксоида - будет кого пинать и доставать своими вопросами. Если охота проявить творчество, можно попросить создать конфиг с умолчальными настройками:

\begin{lstlisting}
# make defaultconfig
\end{lstlisting}

Не увлекайтесь заплатками, особенно поначалу. Каждая из них добавляет возможности в ядро, но может привести к дестабилизации системы и крайне неприятным последствиям. Обзор различных интересных патчей и веток ядер Линукс дан в этой прекрасной статье.


\subsection{Где лежат большие грабли}
Как и всё остальное в Линукс, тексты ядра прокомментированы и можно в процессе сборки попросить помощи. В menuconfig это крайняя правая кнопка HELP. Комментарии есть практически к каждой опции, более или менее внятные, и их стоит почитать, если из статьи не ясно, что это такое.

Перво-наперво, не включайте в ядро и не делайте модулем никаких функций, рядом с которыми написано слово EXPERIMENTAL или DEPRECATED! Это может вывести систему из стабильного состояния и добавить вам совершенно ненужных проблем - включайте только в том случае, если это очень необходимо и вы знаете, что делаете.

Чтобы система после перезагрузке загрузилась с новым ядром, обязательно включите поддержку следующих опций монолитно:
\begin{itemize}
\item файловой системы, которую вы используете на системном диске;
\item файловых систем initramfs и cramfs в меню Device drivers --- Block devices, иначе система не сможет считать стартовый образ ядра;
\item поддержку вашего дискового контроллера в Device drivers --- ATA/ATAPI/MFM/RLL support
\end{itemize}


Чтобы не ломать голову и не думать, почему не работает что-то, имейте в виду:
\begin{itemize}
\item То, что может быть будет подключаться к системе, полезно сделать модулем, то, чем будете пользоваться постоянно - лучше монолитно (об исключениях - ниже).
\item Драйвера для звуковых карт включаются модульно в меню Device drivers --- Sound --- Advanced Linux Sound Architecture --- чтобы потом их проще было конфигурировать (если для этого нет крайней необходимости, не пользуйтесь OSS).
\item Если в системе есть SATA-диски, планируется подключать флешки и писать CD или DVD-диски - не выключайте поддержку SCSI в меню Device drivers --- SCSI device support, так как очень многое в Линукс работает "как протокол поверх SCSI".
\item Если вы планируете пользоваться кардридером, обязательно включите опцию Device drivers --- SCSI device support --- Probe all LUNs on each SCSI device, иначе будете видеть только первый слот.
\item Файловые системы, которые планируется использовать редко, сделайте модулем. Обязательно включите поддержку петлевого устройства в Device drivers --- Block devices --- Loopback device support, иначе не сможете монтировать образы дисков.
\item Корневую файловую систему включайте монолитно в ядро - иначе система не сможет загрузиться.
\item Будьте внимательны, если используете ReiserFS и не включайте все флажки под ним подряд (лучше вообще никаких не ключайте): один из них (указанный здесь пустым) File systems --- Reiserfs support [ ] Enable reiserfs debug mode приводит к замедлению файловой системы и в логах постоянно будет появляться "WARNING! Using reiserfs in slow mode for debugging" или что-то в этом духе. Не включайте этот флажок!
\item В меню Block layer --- IO Schedulers отмечайте ДА на все планировщики ввода-вывода, потом можно будет на лету их менять (по ситуации).
\item Для ноутбуков я бы советовал включать шину ISA в меню Bus options, так как некоторые встроенные устройства прикрепляются именно к ней.
\item Включите поддержку вашей сетевой карты модулем в меню Device drivers --- Network device support --- Device drivers --- Ethernet (10 or 100Mbit) ---
\item Если хочется мониторинг железа, включаем всё модулями в Device drivers --- Hardware Monitoring support --- и сверяемся ещё раз с постом.
\item Не забываем включить поддержку USB и поддержку нужных флешек в Device drivers --- USB support --- USB Mass Storage support
\item Так же стоит сразу включить поддержку оперативной памяти более 1Гб отметив Processor type and features --- High Memory Support (off) --- 4Gb
\end{itemize}

Далее для сборки набираем:

от простого пользователя:

\begin{lstlisting}
make bzImage
\end{lstlisting}

(собрать ядро)

\begin{lstlisting}
make modules
\end{lstlisting}

(собрать модули
от пользователя root:

\begin{lstlisting}
make modules_install
\end{lstlisting}
(установить модули)

\begin{lstlisting}
make install
\end{lstlisting}

(установить ядро)

После того, как ядро собрано, следует создать загрузочный образ (в Дебиане это применяется). Для этого нужно выполнить либо

\begin{lstlisting}
# mkinitramfs -o /boot/initrd-вашаверсияядра вашаверсияядра
\end{lstlisting}

либо (для старых или специфических дистрибутивов)

\begin{lstlisting}
# mkinitrd -o /boot/initrd-%ваша\_версия\_ядра% %ваша\_версия\_ядра%
\end{lstlisting}

То есть например:

\begin{lstlisting}
# mkinitramfs -o /boot/initrd-2.6.20 2.6.20
\end{lstlisting}
% % Лицензия на материалы этого текст
% 
% Материалы сайта "Записки дебианщика" написаны virens и доступны на условиях лицензии Creative Commons Attribution-Non-Commercial-Share Alike 3.0 Unported License. Вы можете копировать, распространять, показывать эту работу, и создавать производные работы в некоммерческих целях на условиях:
% 
% 1) обязательной ссылки на автора (virens, http://mydebianblog.blogspot.com/) и
% 
% 2) распространении любых производных работ на условиях этой же лицензии (ссылка на эту лицензию 
% обязательна!).
% 
% Пожалуйста соблюдайте условия лицензии.
% 
% This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. 
После этого прописываем в загрузчике (скорее всего это будет GRUB):

\begin{lstlisting}
title Debian Linux (2.6.20)
       root (hd0,0)
       kernel /vmlinuz-2.6.20 ro root=/dev/sda1
       initrd /initrd-2.6.20.img
\end{lstlisting}

Номер системы, загружаемой по умолчанию, равен 0. Чтобы определить по умолчанию загрузку вашего нового ядра, либо поместите описывающий его раздел файла, в начало, либо измените номер системы по умолчанию на нужный вам (помните, что номера начинаются с 0) Если вы используете GRUB, после редактирования файла конфигурации вам не нужно выполнять какие-либо команды.
Вот все грабли, на которые я наступал и которые вспомнил. Уважаемые комментаторы приглашаются к конструктивной критике и дополнению вышеописанных подводных камней.
